/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package demo.parallelcore;

import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/*
 * This class demos conditional filter usage for collectoion interface. Which
 * includes
 * 1. Simple filter on collection
 * 2. Combination of predicates filter on collction
 * 3. Grouping collection, also attach filter at the same time
 * @author tyan
*/

public class Conditional  extends DemoHelper  {
    /*
     * Filter products that are out of stock. This is demo for simple filter for
     * one predicate. <p>
     *
     * @return     name list of product that is out of stock
    */
    public static List<String> outOfStock(){
        return products.parallelStream().
                //filter out of stock product
                filter(p -> p.getUnitsInStock() == 0).
                //map product to name
                map(Product::getProductName).
                //get product name list
                collect(Collectors.toList());
    }

    /*
     * Filter products that are in stock. This demo shows case that uses a given
     * predicate concatenate another predicate.
     *
     * @predicate  a predicate that filter on products
     * @return     product lists which fits predicate and in-sotck both
    */
    public static List<String> inStockWithPreicate(Predicate<Product> predicate) {
        //Oher way to do this is filter(isInStock).filter(predicate)
        return products.parallelStream().
                //filter product with predicate and in-stcok
                filter(predicate.and(p -> p.getUnitsInStock() > 0))
                //map product to name
                .map(Product::getProductName).
                //get product name lis
                collect(Collectors.toList());
    }
    /*
     * Filter customers in state and their orders, this is a demo for filter
     * predicate join with other data source
     *
     * @region     region be used to look for customer
     * @return     map from customer to its order list in given state
    */
    public static Map<Customer, List<Order>> customerMapOrdersFromRegion(
            String region) {
        return customers.parallelStream()
                //filter customer in given region
                .filter(c -> region.equals(c.getRegion()))
                //convert customers into a map, which key is customer, value is
                //customer's list of orders
                .collect(
                //Accumulate customers into a Map, key is customer and value
                //is cusromer's orders
                Collectors.<Customer, Customer,List<Order>>toMap(
                    Function.identity(), Customer::getOrders));
    }
}
